package moplayer;

import rwmidi.MidiOutput;
import rwmidi.MidiOutputDevice;
import rwmidi.RWMidi;

public class MyOwnPlayer implements MyPlayerModel {

	MidiOutput output;
	float bpm = 120;

	public MyOwnPlayer() {
		MidiOutputDevice devices[] = RWMidi.getOutputDevices();
		int index = 0;
		for (int i = 0; i < devices.length; i++) {
			String anObject = "Java Sound Synthesizer Sun Microsystems";
			//String anObject = "SimpleSynth";
			if(devices[i].toString().contains(anObject)){
				index = i;
			}
		}
		output = devices[index].createOutput();
		System.out.println(devices[index]);
	}
	
	public MyOwnPlayer(MidiOutput output){
		this.output = output;
	}
	
	/* (non-Javadoc)
	 * @see moplayer.MyOtherPlayer#playNote(moplayer.NoteRT, int)
	 */
	public void playNote(NoteRT note, int channel){
		this.playNote(note.getPitch(), note.getDuration(), note.dynamics, channel);
	}
	
	/* (non-Javadoc)
	 * @see moplayer.MyOtherPlayer#pause(long)
	 */
	public void pause(long duration){
		waitDuration(duration);
	}

	/* (non-Javadoc)
	 * @see moplayer.MyOtherPlayer#playNote(int, long, int, int)
	 */
	public void playNote(int pitch, long duration, int dynamics, int channel){
		output.sendNoteOn(channel, pitch, dynamics);
		waitDuration(duration);
		output.sendNoteOff(channel, pitch, dynamics);
	}

	@Override
	public void waitDuration(long duration) {
		float f = 60000/bpm;
		float ratio = f/500.0f;
		try {
			Thread.sleep(Math.round(duration*ratio));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	/* (non-Javadoc)
	 * @see moplayer.MyOtherPlayer#noteOn(moplayer.NoteRT, int)
	 */
	public void noteOn(NoteRT note, int channel){
		output.sendNoteOn(channel, note.getPitch(), note.getDynamics());
	}
	
	/* (non-Javadoc)
	 * @see moplayer.MyOtherPlayer#noteOff(moplayer.NoteRT, int)
	 */
	public void noteOff(NoteRT note, int channel){
		output.sendNoteOff(channel, note.getPitch(), note.getDynamics());
	}
	
	
	/* (non-Javadoc)
	 * @see moplayer.MyOtherPlayer#setBpm(float)
	 */
	public void setBpm(float bpm) {
		this.bpm = bpm;
	}
	
	
	/* (non-Javadoc)
	 * @see moplayer.MyOtherPlayer#getBpm()
	 */
	public float getBpm() {
		return bpm;
	}
	
	/* (non-Javadoc)
	 * @see moplayer.MyOtherPlayer#setCommand(int)
	 */
	public void setCommand(int channel){
		this.output.sendController(channel, 1, 127);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		MyPlayerModel mo = new MyOwnPlayer();
		mo.playNote(60, 1000, 100, 1);
		mo.playNote(60, 1000, 100, 1);
		mo.playNote(60, 1000, 100, 1);
		mo.setCommand(1);
		mo.playNote(60, 1000, 100, 1);
		mo.playNote(60, 1000, 100, 1);
		mo.playNote(60, 1000, 100, 1);
		mo.playChord(new ChordRT(ChordRT.chords[0]), 1);
		mo.playChord(new ChordRT(ChordRT.chords[1]), 2);
		mo.playChord(new ChordRT(ChordRT.chords[4]), 3);
		//mo.playChord(new ChordRT(ChordRT.chords[3]), 4);
		//mo.playChord(new ChordRT(ChordRT.chords[2]), 5);
//		mo.playChord(new ChordRT(ChordRT.chords[5]), 6);
//		mo.playChord(new ChordRT(ChordRT.chords[5]), 7);
//		mo.playChord(new ChordRT(ChordRT.chords[5]), 8);
//		mo.playChord(new ChordRT(ChordRT.chords[5]), 9);
//		mo.playChord(new ChordRT(ChordRT.chords[5]), 10);
//		mo.playChord(new ChordRT(ChordRT.chords[5]), 11);
//		mo.playChord(new ChordRT(ChordRT.chords[5]), 12);
//		mo.playChord(new ChordRT(ChordRT.chords[5]), 13);
//		mo.playChord(new ChordRT(ChordRT.chords[5]), 14);
	}

	/* (non-Javadoc)
	 * @see moplayer.MyOtherPlayer#playChord(moplayer.ChordRT, int)
	 */
	public void playChord(ChordRT chord, int channel) {
		int[] notes = chord.getNotes();
		for (int i = 0; i < notes.length; i++) {
			output.sendNoteOn(channel, notes[i], chord.dynamics);
		}
		waitDuration(chord.duration);
		for (int i = 0; i < notes.length; i++) {
			output.sendNoteOff(channel, notes[i], chord.dynamics);
		}
	}
	
}
